package com.magenta.maxoptra.gis.distancematrix.commands;

import com.magenta.maxoptra.gis.GeoProviderSettings;
import com.magenta.maxoptra.gis.GisParameter;
import com.magenta.maxoptra.gis.distancematrix.*;
import com.magenta.maxoptra.gis.util.Apis;
import org.apache.commons.lang.StringUtils;

/**
 * @author Sergey Grachev
 */
final class ChangeGeoProviderSettings extends AbstractGroupCommand {

    private final GeoProviderSettings settings;
    private boolean requireMatrixUpdating;

    ChangeGeoProviderSettings(final long groupId, final GeoProviderSettings settings) {
        super(groupId);
        this.settings = settings;
    }

    @Override
    public CommandType getType() {
        return CommandType.CHANGE_GEO_PROVIDER_SETTINGS;
    }

    @Override
    public void execute(final DistanceMatrixDAO db, final DistanceMatrixServiceProxy service) {
        final long newCid = Apis.cid(settings.getProviderName(), settings.getVersionApi(), settings.getCidDiscriminator());
        final GeoProviderSettings oldSettings = groupContext.getGeoProviderSettings();
        if (oldSettings == null) {
            requireMatrixUpdating = db.updateStateForCoordinatesForNewCid(groupId, newCid, UpdatingState.SCHEDULED.getValue());
        } else {
            final String oldRouteProfile = oldSettings
                    .getGisParam(GisParameter.routing_profile.withProvider(oldSettings.getProviderName().toLowerCase()));
            final String newRouteProfile = settings
                    .getGisParam(GisParameter.routing_profile.withProvider(settings.getProviderName().toLowerCase()));
            if (!StringUtils.equals(oldRouteProfile, newRouteProfile)) {
                requireMatrixUpdating = db.resetStatesOfGroup(groupId);
            } else {
                final long oldCid = Apis.cid(oldSettings.getProviderName(), oldSettings.getVersionApi(), oldSettings.getCidDiscriminator());
                if (oldCid != newCid) {
                    service.stopGroupUpdating(groupId);
                    requireMatrixUpdating = db.updateStateForCoordinatesForNewCid(groupId, newCid, UpdatingState.SCHEDULED.getValue());
                }
            }
        }
        groupContext.setGeoProviderSettings(settings);
    }

    @Override
    public UpdateRequestType isRequireMatrixUpdating() {
        return requireMatrixUpdating ? UpdateRequestType.SCHEDULE : UpdateRequestType.NONE;
    }

    @Override
    public boolean isRequireGroupLock() {
        return true;
    }

    @Override
    public String toString() {
        return "ChangeGeoProviderSettings{" +
                "groupId=" + groupId +
                ", settings=" + settings +
                '}';
    }
}
